package control;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Timer;
import java.util.TimerTask;

import model.Ship;


/**
 * Controllo di una ship in uno spazio bidimensionale.
 * In questo caso non viene considerata la Z.
 * @author Jancarlos
 *
 */
public class Controller2D implements KeyListener{
	
	
	private float shift = 10.0f;
	
	private Ship userShip;
	private int directionPressed;
	private final int LEFT = -1;
	private final int RIGHT = 1;
	private Timer timer;
	private boolean started = false;
	private int updateTimeInMillis = 10;
	
	/**
	 * Crea un nuovo controller 2D per la ship.
	 * @param userShip ship da controllare
	 */
	public Controller2D(Ship userShip) {
		this.userShip = userShip;
	}

	public float getShift() {
		return shift;
	}

	public void setShift(float shift) {
		this.shift = shift;
	}

	@Override
	public void keyPressed(KeyEvent e) {
		
		directionPressed =  getDirection( e.getKeyCode()  );
		
		//Grazie Max e Prof u.u
		if(!started){
			started = true;
			timer = new Timer();
			
			TimerTask moveTask = new TimerTask() {
				@Override
				public void run() {
					moveXAxis();
				}
			};
			timer.scheduleAtFixedRate( moveTask, 0, updateTimeInMillis);
		}
	}
	
	@Override
	public void keyReleased(KeyEvent e) {
		started = false;
		timer.cancel();
	}
	
	
	/**
	 * Spostamento lungo l'asse X.
	 */
	public void moveXAxis() {
		//Nel modello verra' definita un metodo/sistema per determinare gli spostamenti
		float newX = userShip.getX() + shift*directionPressed;
		userShip.setX( newX );
	}
	
	
	
	//Metodo utilizzato per la selezione della direzione verso cui muoversi.
	private int getDirection( int keyCode ){
		switch ( keyCode ) {
			case 37:	return LEFT;
			case 39:	return RIGHT;
			default:	return 0;
		}
	}
	
	/**
	 * Restituisce l'attuale tempo di aggiornamento.
	 * @return attuale tempo di aggiornamento
	 */
	public int getUpdateTimeInMillis() {
		return updateTimeInMillis;
	}

	/**
	 * Settaggio del tempo di aggiornamento del timer interno.
	 * Il timer interno viene usato per sopperire alla latenza dovuta al normale KeyListener.
	 * @param updateTimeInMillis Nuovo tempo in millisecondi
	 */
	public void setUpdateTimeInMillis(int updateTimeInMillis) {
		this.updateTimeInMillis = updateTimeInMillis;
	}


	/**
	 * Nessuna azione.
	 */
	@Override
	public void keyTyped(KeyEvent e) {
		//doNathing
	}
	
	/**
	 * Spostamento lungo l'asse Y.
	 */
	public void moveYAxis() {
		//doNathing
	}
	
	/**
	 * Spostamento lungo l'asse Z.
	 */
	public void moveZAxis() {
		//doNathing		
	}
	
}
